using System;
using System.Diagnostics;
using UnityEngine;

namespace BaseLib
{ 

public class AssertException : Exception
{
    public AssertException(string message)
        : base(message)
    {

    }
}

public class Debugger
{
    static protected Action<bool, String> _pAssertFunc = __doAssert;
    static protected Action<object> _pLogFunc = __doLog;

    public static void SetAssertFunction(Action<bool, String> pAssertFunc = null)
    {
        if (pAssertFunc == null) _pAssertFunc = __doAssert;
        else _pAssertFunc = pAssertFunc;
    }

    public static void SetLogFunction(Action<object> pLogFunc = null)
    {
        if (pLogFunc == null) _pLogFunc = __doLog;
        else _pLogFunc = pLogFunc;
    }

    /// [Conditional("UNITY_EDITOR")]
    public static void Log(object message)
    {
        _pLogFunc(message);
    }

    ///[Conditional("UNITY_EDITOR")]
    public static void LogWarning(object strMessage)
    {
#if CONSOLE_LIB
        System.Console.WriteLine(strMessage);  
#else
        UnityEngine.Debug.LogWarning(strMessage);
#endif
    }

    [Conditional("UNITY_EDITOR")]
    public static void LogException(Exception exception)
    {
#if CONSOLE_LIB
        System.Console.WriteLine(exception.Message);  
#else
        UnityEngine.Debug.LogException(exception);
#endif
    }

    [Conditional("UNITY_EDITOR")]
    public static void LogError(string strMessage)
    {
#if CONSOLE_LIB
        System.Console.WriteLine(strMessage);  
#else
        UnityEngine.Debug.LogError(strMessage);
#endif
    }

    [Conditional("UNITY_EDITOR")]
    public static void Assert(bool bCondition, GameObject pGameObject, String message = null)
    {
        if (message == null)
        {
            message = "Hierarchy is:" + GetHierarchy(pGameObject);
        }
        else
        {
            message += ", Hierarchy is:" + GetHierarchy(pGameObject);
        }

        _pAssertFunc(bCondition, message);
    }

	[Conditional("UNITY_EDITOR")]
    public static void Assert(bool bCondition, String message = null)
	{
        _pAssertFunc(bCondition, message);
    }

    [Conditional("UNITY_EDITOR")]
    public static void ConditionalAssert(bool bPreCondition, bool bCondition, String message = null)
    {
        if (bPreCondition)
        {
            _pAssertFunc(bCondition, message);
        }
    }

    static public string GetHierarchy(GameObject obj)
    {
        if (obj == null) return "";
        string path = obj.name;

        while (obj.transform.parent != null)
        {
            obj = obj.transform.parent.gameObject;
            path = obj.name + "\\" + path;
        }
        return path;
    }

    [Conditional("UNITY_EDITOR")]
    public static void DebugSection(Action pCodeFunc)
    {
        pCodeFunc();
    }

    private static void __doLog(object message)
    {
#if CONSOLE_LIB
        System.Console.WriteLine(message);  
#else
        UnityEngine.Debug.Log(message);
#endif
    }

    private static void __doAssert(bool bCondition, String message)
    {
        if (!bCondition) 
		{
			//string str = UnityEngine.StackTraceUtility.ExtractStackTrace ();
			//UnityEngine.Debugger.Log(str);
            throw new AssertException(message);
		}
	}

}

}